<!doctype html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport"
		  content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title>03_js普通对象可以for-of</title>
</head>
<body>
<script>
	let a = [1, 2, 3, 4, 334, 895683];
	console.dir(a);

	// 为obj对象手动添加自己的迭代器，实现普通对象也能for……of，循环遍历
	// 可迭代协议（MDN)：允许js对象定义或定制它们的迭代行为；要求内置类型是内置的可迭代对象，并且有可迭代行为;
	// 例如：Map和Array,Object普通对象obj则无法使用for of

	// let obj = {
	// 	name: '张三',
	// 	age: 18
	// };
	// 添加自定义迭代器
	let obj = {
		name: '张三',
		age: 18,
		[Symbol.iterator]() {
			let index = 0;// index的增加后的值，每次next()后不会立即释放；而是将+1后最新值作为下一次next()的返回值
			let keys = Object.keys(obj);// 获取对象所有的键名组成的数组
			return {
				next() {
					if (index < keys.length) {
						return {
							value: obj[keys[index++]],
							done: false // done: true 表示迭代结束；false 表示迭代未结束
						}
					}
					return {
						value: undefined,
						done: true
					}
				}
			}
		}
	};
	// 3.1 添加自定义迭代器后，尝试for of遍历普通对象obj
	// for of直接遍历普通对象的键值
	/*
	* @打印结果：
	* 对象键值对：张三
	* 对象键值对：18
	*
	*
	*  */
	for (let item of obj) {
		console.log(`对象键值对：${item}`);
	}
	// 3.2 再次尝试对添加自定义迭代器的普通对象obj进行解构赋值
	let [name, age] = obj;
	console.log(`普通对象解构赋值：${name}---${age}`);

	// 3.3 对比普通对象的{}解构
	let obj1 = {
		weight: 801,
		height: 180
	};
	let {weight, height} = obj1;
	console.log(`对象解构赋值：${weight}---${height}`);// 对象解构赋值：80---180

	/**
	 * @Map的用法：
	 * 参考：https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Map/groupBy
	 * 一、Map
	 * 1.1 定义：Map对象保存键值对，并且能够保存键值对的原始插入顺序；键和值都可以是任何值（原始数据或者对象）
	 * 二、Map的属性和方法
	 * 2.1 get/set
	 * 2.2 属性，size，键值对的 数量
	 * Map是可迭代对象，for of 遍历时，返回一个[key,value]数组
	 *
	 *
	 *
	 *
	 * */
	let map = new Map();
	map.set('name', '张三');
	map.set('age', 18);
	map.set('sex', '男');
	console.log(`map对象的size属性：`, map.size);
	console.log(`map对象get方法：`, map.get('name'));
	map.set('age', 29);
	console.log(`map对象get方法：age=`, map.get('age'));
	console.log(`map对象set方法：sex=`, map.get('sex'));
	// 2.2 Map Array可以用for of 遍历；遍历返回[key,value]数组
	for (let [key, value] of map) {
		console.log(`map对象迭代：${key}---${value}`);
	}
	console.log(map);
	console.log(`map是否有属性age:`, map.has('age'));// true

	// 2.3 map属性，也可以跟对象一样设置属性，但是不能被查询到
	let map1 = new Map();
	map1['abc'] = 'abc';
	map1['def'] = 'defg';
	console.log(`map1对象属性：`, map1);
	// 测试到size为0
	console.log(`map1.size对象属性：`, map1.size);// 0
	console.log(map1.has('abc'));//  false


</script>
</body>
</html>
